package com.itlong.cloud.controller.sdkV1.cloud.intercom.server;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.itlong.cloud.POJO.DTO.sdk.CloudTalkSDKAddOrUpdateMediaInfoDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudTalkSDKDeviceMediaBindDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudTalkSDKMediaSaveOrUpdateDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudTalkSDKServerMediaDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.MediaTypeEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.CloudTalkErrorCodeEnum;
import com.itlong.cloud.equip.sdk.ICloudTalkSDKMediaServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.sdk.ICloudTalkSDKServerUserServiceClient;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <desc>
 *      云对讲SDK服务端多媒体资源信息Controller
 * </desc>
 *
 * @createDate 2018/05/21
 */
@RestController
@RequestMapping("/cloud/intercom/server")
public class CloudTalkSDKServerMediaController {

    private static Logger LOG = LoggerFactory.getLogger(CloudTalkSDKServerProjectController.class);

    @Value("${" + PlatformConstants.CLOUDTALK_SDK_USER_TOKEN_KEY + "}")
    private String CLOUDTALK_SDK_USER_TOKEN_KEY;

    @Autowired
    private ICloudTalkSDKServerUserServiceClient iCloudTalkSDKServerUserServiceClient;

    @Autowired
    private ICloudTalkSDKMediaServiceClient iCloudTalkSDKMediaServiceClient;

    /**
     * <desc>
     *     添加或更新多媒体资源信息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/05/21
     */
    @ResponseBody
    @PostMapping(path = "/media/add")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_MEDIA_ADD_OR_UPDATE_LOG_DESC)
    public Object cloudTalkSDKAddOrUpdateMedia(){
        try {

            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            CloudTalkSDKServerMediaDTO cloudTalkSDKServerMediaDTO = HttpProtocolUtil.parseRequestParamToDTO(CloudTalkSDKServerMediaDTO.class, request);
            String appId = cloudTalkSDKServerMediaDTO.getAppId();
            String projectId = cloudTalkSDKServerMediaDTO.getProjectId();
            String mediaJson = cloudTalkSDKServerMediaDTO.getMediaJson();
            // 解密项目id
//            projectId = DesEncryptUtil.projectIdDesEncrypt(projectId) == null ? projectId : DesEncryptUtil.projectIdDesEncrypt(projectId);

            // 校验开发者账号是否有该项目的权限
            List<String> projectIdList = iCloudTalkSDKServerUserServiceClient.getProjectIdByParams(appId);
            if (projectIdList == null || projectIdList.isEmpty() || !projectIdList.contains(projectId)) {
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_CHECKDEVELOPER_AUTH.getErrorCode());
            }

            JSONArray errArray = new JSONArray();
            Date currentTime = new Date();
            List<CloudTalkSDKAddOrUpdateMediaInfoDTO> cloudTalkSDKAddOrUpdateMediaInfoDTOS;
            List<CloudTalkSDKMediaSaveOrUpdateDTO> cloudTalkSDKMediaSaveDTOS = new ArrayList<>();
            List<CloudTalkSDKMediaSaveOrUpdateDTO> cloudTalkSDKMediaUpdateDTOS = new ArrayList<>();
            //解析mediaJson
            try {
                JSONObject parseObject = JSONObject.parseObject(mediaJson);
                cloudTalkSDKAddOrUpdateMediaInfoDTOS = JSONObject.parseObject(parseObject.getString("mediaArr"), new TypeReference<List<CloudTalkSDKAddOrUpdateMediaInfoDTO>>() {
                });
            } catch (Exception e) {
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_PARSE_MEDIAJSON_ERR.getErrorCode(),(Object) mediaJson);
            }
            if (cloudTalkSDKAddOrUpdateMediaInfoDTOS == null || cloudTalkSDKAddOrUpdateMediaInfoDTOS.isEmpty()) {
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_MEDIAARR_FORMAT_ERR.getErrorCode(),cloudTalkSDKAddOrUpdateMediaInfoDTOS);
            }

            // 遍历初步解析得到的mediaJson数据
            outer : for (CloudTalkSDKAddOrUpdateMediaInfoDTO cloudTalkSDKAddOrUpdateMediaInfoDTO:cloudTalkSDKAddOrUpdateMediaInfoDTOS){
                CloudTalkSDKMediaSaveOrUpdateDTO cloudTalkSDKMediaSaveOrUpdateDTO = new CloudTalkSDKMediaSaveOrUpdateDTO();
                // 将解析得到的数据转化成内部传输对象
                BeanUtils.copyProperties(cloudTalkSDKAddOrUpdateMediaInfoDTO,cloudTalkSDKMediaSaveOrUpdateDTO);
                cloudTalkSDKMediaSaveOrUpdateDTO.setProjectId(projectId);

                // 处理投放时间和发布状态
                if (StringUtils.isNotBlank(cloudTalkSDKAddOrUpdateMediaInfoDTO.getPutStartTime()) && StringUtils.isNotBlank(cloudTalkSDKAddOrUpdateMediaInfoDTO.getPutEndTime())) {
                    try {
                        Date putStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(cloudTalkSDKAddOrUpdateMediaInfoDTO.getPutStartTime());
                        Date putEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(cloudTalkSDKAddOrUpdateMediaInfoDTO.getPutEndTime());
                        // 投放开始时间必须小于投放结束时间
                        if (!(putStartTime.compareTo(putEndTime) < 0)){
                            errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源投放时间区间非法，投放开始时间必须小于投放结束时间 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                            continue;
                        }
                        // 存入投放时间
                        cloudTalkSDKMediaSaveOrUpdateDTO.setPutStartTime(putStartTime);
                        cloudTalkSDKMediaSaveOrUpdateDTO.setPutEndTime(putEndTime);
                        // 存入发布状态
                        cloudTalkSDKMediaSaveOrUpdateDTO.setPublishStatus(this.calculateDeviceMediaPublishStatus(putStartTime,putEndTime,currentTime));
                    } catch (ParseException e) {
                        errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源投放时间格式非法 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                        continue;
                    }
                } else {
                    errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源投放时间不能为空 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                    continue;
                }

                // 处理绑定的设备信息
                List<CloudTalkSDKDeviceMediaBindDTO> cloudTalkSDKDeviceMediaBindDTOS;
                try {
                    cloudTalkSDKDeviceMediaBindDTOS = JSONObject.parseObject(cloudTalkSDKAddOrUpdateMediaInfoDTO.getBindInfos(),
                            new TypeReference<List<CloudTalkSDKDeviceMediaBindDTO>>() {});
                } catch (Exception e) {
                    errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源绑定设备解析失败 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                    continue;
                }
                if (cloudTalkSDKDeviceMediaBindDTOS == null || cloudTalkSDKDeviceMediaBindDTOS.isEmpty()) {
                    errArray.add(JSONObject.toJSON(String.format("%s%s", " 请检查多媒体资源绑定设备格式合法性或数量 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                    continue;
                }
                List<CloudTalkSDKDeviceMediaBindDTO> bindDeviceGateInfo = new ArrayList<>();
                List<CloudTalkSDKDeviceMediaBindDTO> bindDeviceWallInfo = new ArrayList<>();
                for (CloudTalkSDKDeviceMediaBindDTO cloudTalkSDKDeviceMediaBindDTO:cloudTalkSDKDeviceMediaBindDTOS){
                    //解密deviceUnique
//                    try {
//                        cloudTalkSDKDeviceMediaBindDTO.setDeviceUnique(DesEncryptUtil.projectIdDesEncrypt(cloudTalkSDKDeviceMediaBindDTO.getDeviceUnique()));
//                    } catch (Exception e) {
//                        errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源绑定设备序列号解密失败 ", cloudTalkSDKDeviceMediaBindDTO.getDeviceUnique())));
//                        continue;
//                    }
//                    if (StringUtils.isBlank(cloudTalkSDKDeviceMediaBindDTO.getDeviceUnique())) {
//                        errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源绑定设备序列号解密失败 ", cloudTalkSDKDeviceMediaBindDTO.getDeviceUnique())));
//                        continue;
//                    }
                    // 先查询该设备的云对讲类型
                    Integer smartType = iCloudTalkSDKMediaServiceClient.getCloudIntercomByProjectIdAndDeviceUnique(projectId,cloudTalkSDKDeviceMediaBindDTO.getDeviceUnique());
                    // 根据smartType属性判断是门口机还是围墙机
                    if (NumberHandlerUtil.isEqual(smartType,PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType())){
                        bindDeviceGateInfo.add(cloudTalkSDKDeviceMediaBindDTO);
                    } else if (NumberHandlerUtil.isEqual(smartType,PropertyEquipTypeEnum.CLOUD_INTERCOM_FENCE.getType())){
                        bindDeviceWallInfo.add(cloudTalkSDKDeviceMediaBindDTO);
                    } else {
                        errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源绑定设备不存在 ", cloudTalkSDKDeviceMediaBindDTO)));
                        continue outer;
                    }
                }
                if (!bindDeviceGateInfo.isEmpty()){
                    cloudTalkSDKMediaSaveOrUpdateDTO.setBindDeviceGateInfo(bindDeviceGateInfo);
                }
                if (!bindDeviceWallInfo.isEmpty()){
                    cloudTalkSDKMediaSaveOrUpdateDTO.setBindDeviceWallInfo(bindDeviceWallInfo);
                }
                // 校验参数
                boolean isRightful = this.checkoutMediaParams(cloudTalkSDKMediaSaveOrUpdateDTO, errArray);
                if (!isRightful){
                    continue;
                }
                if (StringUtils.isBlank(cloudTalkSDKMediaSaveOrUpdateDTO.getMediaId())){
                    // mediaId为空，则添加
                    cloudTalkSDKMediaSaveDTOS.add(cloudTalkSDKMediaSaveOrUpdateDTO);
                } else {
                    // mediaId不为空，通过mediaId查询多媒体资源，若查询到结果，则为修改，查询不到结果，则为错误数据
                    String mediaId = iCloudTalkSDKMediaServiceClient.getMediaIdByProjectIdAndMediaId(projectId,cloudTalkSDKMediaSaveOrUpdateDTO.getMediaId());
                    if (StringUtils.isNotBlank(mediaId)){
                        cloudTalkSDKMediaUpdateDTOS.add(cloudTalkSDKMediaSaveOrUpdateDTO);
                    } else {
                        errArray.add(JSONObject.toJSON(String.format("%s%s", " 要更新的多媒体资源不存在 ", cloudTalkSDKAddOrUpdateMediaInfoDTO)));
                        continue;
                    }
                }
            }

            List<CloudTalkSDKMediaSaveOrUpdateDTO> medias = new ArrayList<>();
            if (!cloudTalkSDKMediaSaveDTOS.isEmpty()){
                List<CloudTalkSDKMediaSaveOrUpdateDTO> cloudTalkSDKMediaSaveOrUpdateDTOS = iCloudTalkSDKMediaServiceClient.saveMedia(cloudTalkSDKMediaSaveDTOS);
                medias.addAll(cloudTalkSDKMediaSaveOrUpdateDTOS);
            }
            if (!cloudTalkSDKMediaUpdateDTOS.isEmpty()){
                List<CloudTalkSDKMediaSaveOrUpdateDTO> cloudTalkSDKMediaSaveOrUpdateDTOS = iCloudTalkSDKMediaServiceClient.updateMedia(cloudTalkSDKMediaUpdateDTOS);
                medias.addAll(cloudTalkSDKMediaSaveOrUpdateDTOS);
            }
            String errStr = "";
            if (errArray.size() > 0) {
                errStr = ",未添加或更新的异常数据：" + errArray.toJSONString();
            }
            int count = cloudTalkSDKAddOrUpdateMediaInfoDTOS.size() - errArray.size();
            if (count > 0) {
//                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),(Object) String.format("%s%s", "本次总共添加或更新了：" + count + " 条数据", errStr));
                //保存生成操作日志所需信息 详细描述和接口类别
                request.setAttribute("remark",projectId + "添加或更新多媒体资源信息");
                request.setAttribute("portType",LogDescConstant.SDK_CLOUD_TALK_TYPE_LOG_DESC);
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),medias);
            }
            return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(),(Object) ("添加的数据已存在,或存在异常的数据" + errStr));

        } catch (Exception e) {
            throw new DataAccessException("【SDK_服务端_项目多媒体资源服务】添加或更新多媒体资源失败",e);
        }
    }

    /**
     * <desc>
     *     校验多媒体资源各参数对象的合法性
     * </desc>
     *
     * @param cloudTalkSDKMediaSaveOrUpdateDTO 云对讲SDK多媒体资源保存或更新传输对象，内部使用
     * @param errArray 错误数据集合
     * @return true校验通过，false校验不通过
     * @author wangzhi
     * @createDate 2018/05/21
     */
    private boolean checkoutMediaParams(CloudTalkSDKMediaSaveOrUpdateDTO cloudTalkSDKMediaSaveOrUpdateDTO,JSONArray errArray){
        //判断参数合法性
        if (null == cloudTalkSDKMediaSaveOrUpdateDTO){
            errArray.add(JSONObject.toJSON(" 缺少必要参数 "));
            return false;
        }

        //多媒体标题合法性
        if (StringUtils.isBlank(cloudTalkSDKMediaSaveOrUpdateDTO.getTitle())){
            errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源标题不能为空 ", cloudTalkSDKMediaSaveOrUpdateDTO)));
            return false;
        }
        if (cloudTalkSDKMediaSaveOrUpdateDTO.getTitle().length() > PlatformConstants.MEDIA_TITLE_MAX_LENGTH){
            errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源标题过长 ", cloudTalkSDKMediaSaveOrUpdateDTO)));
            return false;
        }

        // 多媒体资源绑定设备列表或地址列表不能为空
        if ((cloudTalkSDKMediaSaveOrUpdateDTO.getBindDeviceGateInfo() == null || cloudTalkSDKMediaSaveOrUpdateDTO.getBindDeviceGateInfo().isEmpty()) &&
                (cloudTalkSDKMediaSaveOrUpdateDTO.getBindDeviceWallInfo() == null || cloudTalkSDKMediaSaveOrUpdateDTO.getBindDeviceWallInfo().isEmpty())){
            errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源绑定设备不能为空 ", cloudTalkSDKMediaSaveOrUpdateDTO)));
            return false;
        }

        // 多媒体资源类型的合法性，1-3之间
        Integer mediaType = cloudTalkSDKMediaSaveOrUpdateDTO.getType();
        if (!NumberHandlerUtil.isInRange(mediaType, MediaTypeEnum.TEXT.getType(),MediaTypeEnum.VIDEO.getType())){
            errArray.add(JSONObject.toJSON(String.format("%s%s", " 多媒体资源类型type不合法 ", cloudTalkSDKMediaSaveOrUpdateDTO)));
            return false;
        }

        return true;
    }

    /**
     * <desc>
     *     根据多媒体资源投放开始和结束时间推算多媒体资源的发布状态
     * </desc>
     *
     * @param putStartTime 多媒体资源投放开始时间
     * @param putEndTime 多媒体资源投放结束时间
     * @param date 用来比较的基准时间
     * @return 多媒体资源发布状态
     * @author wangzhi
     * @createDate 2018/05/21
     */
    private Integer calculateDeviceMediaPublishStatus(Date putStartTime, Date putEndTime, Date date){
        // publishStatus 发布状态0-已过期 1-已发布 2-未发布
        if (putStartTime.compareTo(date) > 0){
            // 投放开始时间大于date，未发布
            return 2;
        }
        if (putStartTime.compareTo(date) < 0 && putEndTime.compareTo(date) >0){
            // date在投放时间区间中，已发布
            return 1;
        }
        if (putEndTime.compareTo(date) < 0){
            // 投放结束时间小于date，已过期
            return 0;
        }
        return null;
    }

}
